package server.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.demo.dto.CreateCarriageRequest;
import server.demo.dto.CarriageDTO;
import server.demo.entity.Carriage;
import server.demo.entity.Train;
import server.demo.repository.CarriageRepository;
import server.demo.repository.TrainRepository;
import server.demo.repository.SeatRepository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class CarriageService {
    
    @Autowired
    private CarriageRepository carriageRepository;
    
    @Autowired
    private TrainRepository trainRepository;
    
    @Autowired
    private SeatRepository seatRepository;
    
    public List<CarriageDTO> getAllCarriages() {
        List<Carriage> carriages = carriageRepository.findAll();
        return carriages.stream()
                .map(carriage -> {
                    CarriageDTO dto = new CarriageDTO(carriage);
                    // 获取该车厢的可用座位数
                    List<server.demo.entity.Seat> availableSeats = seatRepository.findAvailableSeatsByCarriageId(carriage.getId());
                    dto.setAvailableSeats(availableSeats.size());
                    return dto;
                })
                .collect(Collectors.toList());
    }
    
    public List<CarriageDTO> getCarriagesByTrainId(Long trainId) {
        List<Carriage> carriages = carriageRepository.findByTrainIdOrderByCarriageNumber(trainId);
        return carriages.stream()
                .map(carriage -> {
                    CarriageDTO dto = new CarriageDTO(carriage);
                    // 获取可用座位数
                    Long availableSeats = seatRepository.countAvailableSeatsByTrainId(carriage.getTrain().getId());
                    dto.setAvailableSeats(availableSeats.intValue());
                    return dto;
                })
                .collect(Collectors.toList());
    }
    
    public Optional<CarriageDTO> getCarriageById(Long id) {
        return carriageRepository.findById(id)
                .map(carriage -> {
                    CarriageDTO dto = new CarriageDTO(carriage);
                    // 获取该车厢的可用座位数
                    List<server.demo.entity.Seat> availableSeats = seatRepository.findAvailableSeatsByCarriageId(carriage.getId());
                    dto.setAvailableSeats(availableSeats.size());
                    return dto;
                });
    }
    
    public CarriageDTO createCarriage(CreateCarriageRequest request) {
        Optional<Train> train = trainRepository.findById(request.getTrainId());
        if (train.isEmpty()) {
            throw new RuntimeException("车次不存在");
        }
        
        if (carriageRepository.existsByTrainIdAndCarriageNumber(request.getTrainId(), request.getCarriageNumber())) {
            throw new RuntimeException("该车次的车厢号已存在");
        }
        
        Carriage carriage = new Carriage();
        carriage.setTrain(train.get());
        carriage.setCarriageNumber(request.getCarriageNumber());
        carriage.setCarriageType(Carriage.CarriageType.valueOf(request.getCarriageType()));
        carriage.setTotalSeats(request.getTotalSeats());
        
        Carriage savedCarriage = carriageRepository.save(carriage);
        
        // 自动生成座位
        generateSeats(savedCarriage);
        
        CarriageDTO dto = new CarriageDTO(savedCarriage);
        dto.setAvailableSeats(request.getTotalSeats()); // 新创建的车厢所有座位都可用
        return dto;
    }
    
    public CarriageDTO updateCarriage(Long id, CreateCarriageRequest request) {
        Optional<Carriage> carriageOpt = carriageRepository.findById(id);
        if (carriageOpt.isEmpty()) {
            throw new RuntimeException("车厢不存在");
        }
        
        Carriage carriage = carriageOpt.get();
        
        // 如果车厢号改变，检查是否冲突
        if (!carriage.getCarriageNumber().equals(request.getCarriageNumber()) && 
            carriageRepository.existsByTrainIdAndCarriageNumber(carriage.getTrain().getId(), request.getCarriageNumber())) {
            throw new RuntimeException("该车次的车厢号已存在");
        }
        
        carriage.setCarriageNumber(request.getCarriageNumber());
        carriage.setCarriageType(Carriage.CarriageType.valueOf(request.getCarriageType()));
        carriage.setTotalSeats(request.getTotalSeats());
        
        Carriage savedCarriage = carriageRepository.save(carriage);
        return new CarriageDTO(savedCarriage);
    }
    
    public void deleteCarriage(Long id) {
        if (!carriageRepository.existsById(id)) {
            throw new RuntimeException("车厢不存在");
        }
        carriageRepository.deleteById(id);
    }
    
    private void generateSeats(Carriage carriage) {
        // 根据车厢类型和座位数自动生成座位
        int totalSeats = carriage.getTotalSeats();
        String prefix = getSeatPrefix(carriage.getCarriageType());
        
        // 简化的座位生成逻辑
        for (int i = 1; i <= totalSeats; i++) {
            String seatNumber = String.format("%d%s", (i - 1) / 5 + 1, getSeatSuffix(i % 5));
            
            server.demo.entity.Seat seat = new server.demo.entity.Seat();
            seat.setCarriage(carriage);
            seat.setSeatNumber(seatNumber);
            seat.setSeatType(getSeatTypeByPosition(i % 5));
            seat.setPrice(getSeatPrice(carriage.getCarriageType()));
            seat.setIsAvailable(true);
            
            seatRepository.save(seat);
        }
    }
    
    private String getSeatPrefix(Carriage.CarriageType type) {
        switch (type) {
            case FIRST_CLASS:
                return "A";
            case SECOND_CLASS:
                return "B";
            case SLEEPER:
                return "S";
            default:
                return "S";
        }
    }
    
    private String getSeatSuffix(int position) {
        String[] suffixes = {"A", "B", "C", "D", "F"};
        return suffixes[position];
    }
    
    private server.demo.entity.Seat.SeatType getSeatTypeByPosition(int position) {
        if (position == 0 || position == 4) {
            return server.demo.entity.Seat.SeatType.WINDOW;
        } else if (position == 2) {
            return server.demo.entity.Seat.SeatType.AISLE;
        } else {
            return server.demo.entity.Seat.SeatType.MIDDLE;
        }
    }
    
    private java.math.BigDecimal getSeatPrice(Carriage.CarriageType type) {
        switch (type) {
            case FIRST_CLASS:
                return new java.math.BigDecimal("553.50");
            case SECOND_CLASS:
                return new java.math.BigDecimal("350.50");
            case SLEEPER:
                return new java.math.BigDecimal("450.00");
            default:
                return new java.math.BigDecimal("200.00");
        }
    }
}